const {getDmg,reduceResistanceK,lvSuppressK,objValueAdd } = require("../libs/apis.js")

const WEAPONS = require("./weapons.js");

const CLIPDATA_TYPE = {
    max:{
        fixedhp: 298.75,
        fixedAtt: 19.45,
        fixdefence: 23.15,
        reaction : 23.31,
        attRate: 5.83, 
        hpRate: 5.83, 
        criticalRate: 3.89,
        criticalStrike: 7.77,
        defRate: 7.29,
        charging: 6.48
    },
    mid:{
        fixedhp: 253.94,   // 209.13  239   268.88   298.75
        fixdefence: 19.675, // 16.2   18.52  20.83  23.15
        fixedAtt: 16.535,   //  13.62   15.56   17.51  19.45
        reaction : 19.815,  // 16.32   18.65  20.98  23.31
        attRate: 4.955,  // 4.08  4.66  5.25  5.83
        hpRate: 4.955,   // 4.08  4.66  5.25  5.83
        criticalRate: 3.305,   //  2.72  3.11   3.5   3.89
        criticalStrike: 6.605,  //  5.44  6.22  6.99  7.77
        defRate: 6.195,   //  5.1  5.83  6.56   7.29
        charging: 5.505  //  4.53   5.18   5.83   6.48
    }
}

const CLIPDATA = CLIPDATA_TYPE.mid

const CONFIG = {
    chance: 4,
    your_lv: 90,
    enemy_lv: 90,
    clips_main: {
        fixedHp: 4780,
        fixedAtt:311,
        reaction: 187,
        dmgRate: 46.6,
        criticalRate: 31.1,
    },
    clips_initial: [
        ["reaction", "attRate", "criticalRate", "criticalStrike"],
        ["reaction", "attRate", "criticalRate", "criticalStrike"],
        ["charging", "attRate", "criticalRate", "criticalStrike"],
        ["reaction", "attRate", "criticalRate", "criticalStrike"],
        ["charging", "attRate", "reaction", "criticalStrike"]
    ],
    reactionK : 2,
    reactionDmgAdd: 0,
    buffs: [  
        { reaction: 80 + 50*3},  // 饰金
        // { dmgRate: 15, jk: 30},  // 草套
    ]
}

let charaters = {
    units : {
        name: "琳妮特", 
        dmgZhi: 0,
        charging: 100,
        dmgRate: 24,
        defRate: 0,
        defence: 546.02,
        weapontype: "sword",
        attRate: 0,
        hp:12180,
        base: 232,    
        criticalRate: 5,    
        criticalStrike: 50,
        skills: {
            a: [
                function(data){},
            ]
        }
    },
}

let tmp = {}
CONFIG.clips_initial.forEach(item => {
    item.forEach(item2 => {
        if(tmp[item2]) {
            tmp[item2] += 1
        } else {
            tmp[item2] = 1
        }
    })
});
/*
    e 点按: 单次草伤 自身挂草 草盾 按住：提升速度等冲撞敌人造成草伤 草盾 松开后进行爪击  护盾持续12s 长按时间越长 cd越长
    lv10 点按伤害:187.2% 护盾:18%hp+2117.07 护盾上限:28.8%hp+3390.63 长按冲撞伤害:60.48% 爪击伤害259.2% cd 8~12s
    lv13 点按伤害:221% 护盾:21.25%hp+2646.37 护盾上限:34%hp+4238.34 长按冲撞伤害:67.2% 爪击伤害288% cd 8~12s
    q 一次高倍率范围草伤害 产生一些猫草豆蔻 猫草豆蔻接触敌人爆炸范围草伤
    lv10  q倍率 1026.43%  猫草豆蔻64.15%   cd/能量(15/60)
    lv13  q倍率 1211.76%  猫草豆蔻75.74%   cd/能量(15/60)
    天赋 接近产出坤肉和兽肉动物时不惊扰动物
    e长按撞击敌人时候叠加护盾(叠加e盾的20% 不能超过e盾上限 可以叠加3次)
    每1000血 提升e0.4%增伤 q0.3%增伤
    命座: 1   每8000血增加q一个豆蔻 最多加4个
          2   e长按碰到联机队友 给队友套盾 盾效果是e的40% (单人相当于废命座)
          3   e+3
          4   套盾后用平a类攻击命中敌人 每3.8s产生一个200%倍率的豆蔻炸敌人
          5   q+3
          6   释放e或q后15s内全队12增伤
*/

let cons = 6 // 命座
let chooseIndex = 5; // 查看结果索引
let cid = "units"
let count_kit = 0;
let combination = getCombination(Array(5*CONFIG.chance + 1).fill().map((_,i)=>i), CONFIG.chance, Object.entries(tmp))
let clips_initial_data = calc_clips_initial()
let fs = require("fs")
calc(combination);
function calc(clipSecondData) {
    let charactersDmg = [];
    clipSecondData = clipSecondData.map(clipSecondDataItem => {
        let clipSecond = {}
        clipSecond.des = clipSecondDataItem;
        clipSecond.data = {} 
        for (let secondKey in clipSecond.des) {
            let count =  clipSecond.des[secondKey]
            clipSecond.data[secondKey] = count * CLIPDATA[secondKey]
        }
        return clipSecond
    })
    
    Object.values(WEAPONS).forEach(weapon => {
        if(charaters[cid].weapontype && weapon.weapontype != charaters[cid].weapontype && weapon.weapontype!="all") {return}
        charactersDmg.push(getDMG([charaters[cid],weapon,clips_initial_data,{...CONFIG.clips_main}], clipSecondData, (data,second) => {
            count_kit++;
            data = objValueAdd([data, ...CONFIG.buffs]);
            data.hp = data.hp*(1 + (data.hpRate||0)/100) + data.fixedHp;
            
            if(weapon.skill) { weapon.skill(data); }
            
            if(cons >= 4) {
                data.reaction += 160
            }

            // 站q内时加精通
            let reaAdd = data.reaction * 0.25
            if(reaAdd > 250) {reaAdd = 250}
            data.reaction += reaAdd 

            let rea = { reaction:data.reaction, reactionQ:CONFIG.reactionK, reactionDmgAdd:data.reactionDmgAdd || 0 }
            
            // 根据草神精通超过200的部分提升e灭净三业双爆  每点精通提升(0.1/0.03) 最高提升80/24
            let eMJCR = (data.reaction>200?data.reaction - 200 : 0) * 0.03
            if(eMJCR > 24) { eMJCR = 24 }
            let eMJDmg = (data.reaction>200?data.reaction - 200 : 0) * 0.1
            if(eMJDmg > 80) { eMJDmg = 80 }
           
            data.eDmgRate = data.eDmgRate||0;
            // q加成
            if(cons >= 5) {
                data.eDmgRate += 47.43
            } else if(cons >= 1) {
                data.eDmgRate += 40.18
            } else {
                data.eDmgRate += 26.78
            }

            let jf = 0
            if(cons >= 2) {
                jf = 30
            }

            // lv10 短按 1.771 长按 2.347 灭净三业: 1.8576 + 3.7152精通
            // lv13 短按 2.091 长按 2.771 灭净三业: 2.193 + 4.386精通
            let eRateList = [2.347, 1.8576, 3.7152]
            if(cons >= 3) {
                eRateList = [2.771, 2.193, 4.386]
            }
            let jhDmgZhi = 1447 * 1.25 * (1 + (5*data.reaction)/(data.reaction+1200))
            // 普攻重击倍率 0.7255 0.6655 0.8257  1.0513      重击 2.376 
            let a1Dmgage = getDmg({
                data: {
                    ...data,
                    dmgRate: data.dmgRate + (data.a1dmg||0),
                },
                rate: 0.7255
            }).qw * reduceResistanceK(10 - (data.jk||0)) * lvSuppressK(CONFIG.your_lv, CONFIG.enemy_lv, jf);
            let a1DmgageJH = getDmg({
                data: {
                    ...data,
                    dmgRate: data.dmgRate + (data.a1dmg||0),
                    dmgZhi: jhDmgZhi
                },
                rate: 0.7255
            }).qw * reduceResistanceK(10 - (data.jk||0)) * lvSuppressK(CONFIG.your_lv, CONFIG.enemy_lv, jf);
            let a2Dmgage = getDmg({
                data: {
                    ...data,
                    dmgRate: data.dmgRate + (data.a1dmg||0),
                },
                rate: 0.6655
            }).qw * reduceResistanceK(10 - (data.jk||0)) * lvSuppressK(CONFIG.your_lv, CONFIG.enemy_lv, jf);
            let a2DmgageJH = getDmg({
                data: {
                    ...data,
                    dmgRate: data.dmgRate + (data.a1dmg||0),
                    dmgZhi: jhDmgZhi
                },
                rate: 0.6655
            }).qw * reduceResistanceK(10 - (data.jk||0)) * lvSuppressK(CONFIG.your_lv, CONFIG.enemy_lv, jf);
            let a3Dmgage = getDmg({
                data: {
                    ...data,
                    dmgRate: data.dmgRate + (data.a1dmg||0),
                },
                rate: 0.8257
            }).qw * reduceResistanceK(10 - (data.jk||0)) * lvSuppressK(CONFIG.your_lv, CONFIG.enemy_lv, jf);
            let a3DmgageJH = getDmg({
                data: {
                    ...data,
                    dmgRate: data.dmgRate + (data.a1dmg||0),
                    dmgZhi: jhDmgZhi
                },
                rate: 0.8257
            }).qw * reduceResistanceK(10 - (data.jk||0)) * lvSuppressK(CONFIG.your_lv, CONFIG.enemy_lv, jf);
            let a4Dmgage = getDmg({
                data: {
                    ...data,
                    dmgRate: data.dmgRate + (data.a1dmg||0),
                },
                rate: 1.0513
            }).qw * reduceResistanceK(10 - (data.jk||0)) * lvSuppressK(CONFIG.your_lv, CONFIG.enemy_lv, jf);
            let a4DmgageJH = getDmg({
                data: {
                    ...data,
                    dmgRate: data.dmgRate + (data.a1dmg||0),
                    dmgZhi: jhDmgZhi
                },
                rate: 1.0513
            }).qw * reduceResistanceK(10 - (data.jk||0)) * lvSuppressK(CONFIG.your_lv, CONFIG.enemy_lv, jf);

            let eShiFang = getDmg({
                data: {
                    ...data,
                    dmgRate: data.dmgRate + (data.eDmgRate||0) + (data.eDmgAdd||0),
                },
                rate: eRateList[0]
            }).qw * reduceResistanceK(10 - (data.jk||0)) * lvSuppressK(CONFIG.your_lv, CONFIG.enemy_lv, jf);
            let eShiFangJH = getDmg({
                data: {
                    ...data,
                    dmgRate: data.dmgRate + (data.eDmgRate||0) + (data.eDmgAdd||0),
                    dmgZhi: jhDmgZhi
                },
                rate: eRateList[0]
            }).qw * reduceResistanceK(10 - (data.jk||0)) * lvSuppressK(CONFIG.your_lv, CONFIG.enemy_lv, jf);
            let eMJ = getDmg({
                data: {
                    ...data,
                    criticalRate: data.criticalRate + eMJCR,
                    dmgRate: data.dmgRate + (data.eDmgRate||0) + eMJDmg  + (data.eDmgAdd||0),
                    dmgZhi: data.reaction * eRateList[2]
                },
                rate: eRateList[1]
            }).qw * reduceResistanceK(10 - (data.jk||0)) * lvSuppressK(CONFIG.your_lv, CONFIG.enemy_lv, jf);
            let eMJJH = getDmg({
                data: {
                    ...data,
                    criticalRate: data.criticalRate + eMJCR,
                    dmgRate: data.dmgRate + (data.eDmgRate||0) + eMJDmg  + (data.eDmgAdd||0),
                    dmgZhi: jhDmgZhi + data.reaction * eRateList[2]
                },
                rate: eRateList[1]
            }).qw * reduceResistanceK(10 - (data.jk||0)) * lvSuppressK(CONFIG.your_lv, CONFIG.enemy_lv, jf);
            
            let eMJLiuMin = getDmg({
                data: {
                    ...data,
                    criticalRate: data.criticalRate + eMJCR,
                    dmgRate: data.dmgRate + (data.eDmgRate||0) + eMJDmg  + (data.eDmgAdd||0),
                    dmgZhi: data.reaction * 4
                },
                rate: 2
            }).qw * reduceResistanceK(10 - (data.jk||0)) * lvSuppressK(CONFIG.your_lv, CONFIG.enemy_lv, jf);
            let eMJLiuMinJH = getDmg({
                data: {
                    ...data,
                    criticalRate: data.criticalRate + eMJCR,
                    dmgRate: data.dmgRate + (data.eDmgRate||0) + eMJDmg  + (data.eDmgAdd||0),
                    dmgZhi: jhDmgZhi + data.reaction * 4
                },
                rate: 2
            }).qw * reduceResistanceK(10 - (data.jk||0)) * lvSuppressK(CONFIG.your_lv, CONFIG.enemy_lv, jf);
            
            

            if(data.phyRate) { // 物理特效伤害
                data.phyDmg = getDmg({data:{...data, dmgRate:0}, rate:data.phyRate}).qw * reduceResistanceK(10) * lvSuppressK(CONFIG.your_lv, CONFIG.enemy_lv);  // 
            }

            // 0命9hit 1命10hit 5命10hit      0.45 0.67 0.79 2.05/1.83/1.71
            let point = eShiFang * 1 + eMJ * 0 + eMJJH*(cons>1? 8 : 7) + (data.phyDmg||0) + (a1DmgageJH + a2Dmgage + a3Dmgage + a4DmgageJH) * 3;
            if(cons >= 6) {
                point += (eMJLiuMin * 3 + eMJLiuMinJH*3)
            }
            let attack = data.base *(1 + data.attRate/100) + data.fixedAtt;
            return {point, data, second, attack, dmg:{eShiFang,eShiFangJH,eMJ,eMJJH,eMJLiuMin,eMJLiuMinJH,reaAdd,jhDmgZhi, aDmg: {
                a1Dmgage,a1DmgageJH,a2Dmgage,a2DmgageJH,a3Dmgage,a3DmgageJH,a4Dmgage,a4DmgageJH
            }}}
        }))
    })
    
    charactersDmg.sort((a,b)=>{
        return (b.point)-(a.point);
    });
    let sortf = JSON.parse(fs.readFileSync("./sort.js").toString()) 
    let choose = charactersDmg[chooseIndex];
    console.log(choose);
    fs.writeFileSync("./ret.js", JSON.stringify(choose))

    let name = choose.data.name
    let keys = "_"+choose.data.weaponname+"_6命无拐2+2毕业"
    let sortfData = {key: name+keys, point:choose.point, dmg:JSON.parse(JSON.stringify(choose.dmg))}
    if(sortfData.point && sortfData.point > 0) {
        let org = sortf.findIndex(item3 => item3.key == sortfData.key)
        if(org >= 0){
            sortf[org] = sortfData
        } else {
            sortf.push(sortfData)
        }
        sortf.sort((b,a) => a.point-b.point)
        // fs.writeFileSync("./sort.js", JSON.stringify(sortf))
    }
    console.log(charactersDmg.map((v, n)=>{
        return  `(${n})得分: ${v.data.weaponname} : ${v.point.toFixed(0)}`
    }));
    console.log(count_kit);
}

function getDMG(dataarr, clipSecond, getRet){
    clipSecond = clipSecond.map(second => {
        let panel = objValueAdd([...dataarr, second.data]);
        return  getRet(panel, second)
    })
    clipSecond.sort((b,a)=> a.point-b.point)
    return clipSecond[0]
}

function calc_clips_initial () {
    let clips = CONFIG.clips_initial.map(v => {
        let tmp = {};
        v.forEach(v2 => {
            tmp[v2] = CLIPDATA[v2]
        })
        return tmp
    })
    let data = {}
    clips.forEach(item => {
        for (const key in item) {
            data[key] = data[key]? (data[key]+item[key]) : item[key]
        }
    })
    return data
}
function getCombination (arr, chance, entrys) {
    let num = 5
    var r = [];
    (function f(t, a, n) {
        if (n === 0) {
            if(t.reduce((a1,b1) => a1+b1) !== chance * 5){return}
            let ret = {}
            for (let i in t) {
                if(t[i] > entrys[i][1]*chance){return}
                ret[entrys[i][0]] = t[i]
            }
            r.push(ret)
            return ;
        }
        for (var i = 0, l = a.length; i < l; i++) {
            f(t.concat(a[i]), a, n - 1);
        }
    })([], arr, num);
    return r;
}